#!/usr/bin/python 

'''
NurbsCad
Archivo gui.py
Autor: Gustavo Enrique Bellino
Contacto: gushbellino@gmail.com
Fecha: Junio de 2009
Descripcion: archivo que carga los modulos que se utilizan en el cad, carga los menues y crea un area para renderizar objetos con OpenGL
Licencia: GNU Public License version 2
'''

#Importa librerias de sistema
import os, sys
import pygtk, os
pygtk.require('2.0')
from gtk.gtkgl.apputils import *
import gtk

#Importa los modulos necesarios para manejar la escenea y exportar los objetos
from escena import Escena
from lib.euclid import Vector3
from xmlParser import xmlNurbParser

#los objetos que maneja la clase
path = os.path.join(os.getcwd(), 'mod/modules.py')
try:
    execfile(path)
except:
    print 'Existe un problema en el archivo modules.py, corrobore su existencia, permisos y/o estructura.'
    sys.exit()



class Interfaz(gtk.Window, GLScene, GLSceneButton, GLSceneButtonMotion):
    ''' Clase que lee de un archivo (xml) creado con glade una interfaz. Crea los menues y un area de trabajo donde es posible renderizar
   elementos creados con openGL '''
    def __init__(self):
        ''' Inicializa la interfaz (menues y area de trabajo), no necesita parametros.'''
        path = os.path.join(os.getcwd(), 'interface/interface.glade')
        try:
            #intenta abrir el archivo con la interfaz
            self.vent = gtk.glade.XML(path)
        except:
            #retorna un error y termina el programa
            print 'Existe un problema en el archivo interface.glade, corrobore su existencia, permisos y/o estructura.'
            sys.exit()
            
        #Menues
        self.connectMenuActions()
        self.createAddDelMenu()
        self.addTableRapidButtons()
        self.initializeTree()
        
        #Obtenemos el contenedor para colocar el GLArea
        self.hbox = self.vent.get_widget('box_opengl1')
        #se llama a escena, la cual hereda GLScene, GLSceneButton, GLSceneButtonMotion que sirven para manejar opengl
        self.escena = Escena(self) 
        self.glarea = gtk.gtkgl.apputils.GLArea(self.escena)
        
        #callback  scroll para pasarlo a la escena 
        self.glarea.connect("scroll_event", self.canvas_button_scroll)
        
        self.glarea.set_size_request(450,450)
        self.glarea.show()
        
        #objetos que maneja la escena
        objetos = self.escena.getObject()
        self.cargarTree(objetos)
        
        #agrega el glarea al hbox
        self.hbox.pack_start(self.glarea, expand=True, fill=True)
        self.glarea.show()
        
        #la camara es el primer objeto seleccionado
        #self.escena.selectedObject = self.escena.camara
        self.escena.selectedObject = self.escena.getObject(1)
        
        #deprecated
        self.vent.get_widget('verArbolDeObjetos').connect('button_press_event', self.enableArbol)
        
        #redibuja la escena
        self.escena.queue_draw()
        
        #boton para salir
        dic={"gtk_main_quit": gtk.main_quit}
        self.vent.signal_autoconnect(dic)
        #redibuja la escena
        self.escena.queue_draw()

    def connectMenuActions(self):
        ''' Setea los botones con las acciones del menu principal'''
        self.vent.get_widget('openProject').connect('button_press_event', self.openProject)
        self.vent.get_widget('saveProject').connect('button_press_event', self.saveProject)
        self.vent.get_widget('buttonCancelCreateElement').connect('clicked', self.cancelCreateNewElement)
        self.vent.get_widget('buttonCreateElement').connect('clicked', self.createAndAddNewElement)
        self.vent.get_widget('quitProgram').connect("button_press_event",lambda p1,  p2: gtk.main_quit())
        return

    def createAddDelMenu(self):
        #Agrega submenues para agregar y eliminar objetos
        menubarAdd = self.vent.get_widget('addObjects')
        menubarDel = self.vent.get_widget('delObjects')
        cont = 0
        for ob in ALLOWED_CLASSES:
            nameClass = str(ob.getClassName())
            nameMenu = str(ob.getNameInMenu())
            #create objects
            menuitem = gtk.Action('', nameMenu, '', None).create_menu_item()
            menubarAdd.append(menuitem)
            menuitem.connect('button_press_event', self.createNewElement, nameClass)
            #delete objects
            menuitem = gtk.Action('', nameMenu, '', None).create_menu_item()
            menubarDel.append(menuitem)
            menuitem.connect('button_press_event', self.deleteElement, nameClass)
            cont += 1
        
        #Se agrega la opcion delete all objects
        name = 'Todos'
        menuitem = gtk.Action('', name, '', None).create_menu_item()
        menubarDel.append(menuitem)
        menuitem.connect('button_press_event', self.deleteElement, name)
        return

    def addTableRapidButtons(self):
        '''Agrega y conecta los botones de la caja de botones rapidos '''
        path = os.path.join(os.getcwd(), 'icons/')
        buttons = [
        {'path':path+"openProject.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'clickedCallback':self.openProject, 
        'toolTip':'Abrir un modelo', 
        'releaseCallback':self.releaseAction}, 
        
        {'path':path+"saveProject.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Guardar un modelo', 
        'clickedCallback':self.saveProject, 
        'releaseCallback':self.releaseAction},         
        
        {'path': path+"createNurb.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'clickedCallback':self.newNurb, 
        'toolTip':'Crear una NURBS', 
        'releaseCallback':self.releaseAction},       
       
        {'path':  path+"camaraActive.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Activar la rotacion con la camara', 
        'clickedCallback': lambda x: self.escena.camara.activePan(False), 
        'releaseCallback':self.releaseAction},              
        
        {'path': path+"panActive.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Activar el Paneo de la camara', 
        'clickedCallback': lambda x: self.escena.camara.activePan(), 
        'releaseCallback':self.releaseAction},            
        
        {'path': path+"zoomIn.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Acercar la camara', 
        'clickedCallback': lambda x: self.escena.camara.zoomIn(), 
        'releaseCallback':self.releaseAction},    
        
        {'path': path+"zoomOut.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Alejar la camara', 
        'clickedCallback': lambda x: self.escena.camara.zoomOut(), 
        'releaseCallback':self.releaseAction},    
        
        {'path': path+"x_y.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Vista del plano x-y', 
        'clickedCallback': lambda x: self.escena.camara.view_x_y(20), 
        'releaseCallback':self.releaseAction},    
        
        {'path': path+"z_x.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Vista del plano z-x', 
        'clickedCallback': lambda x: self.escena.camara.view_x_z(20), 
        'releaseCallback':self.releaseAction},   
        
        {'path': path+"y_z.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Vista del plano y-z', 
        'clickedCallback': lambda x: self.escena.camara.view_y_z(20), 
        'releaseCallback':self.releaseAction},   
        
#        {'path': path+"ligths.png",  #TODO 
#        'widget':self.vent.get_widget('tableCamaraButtons'), 
#        'toolTip':'Activar las luces de la escena', 
#        'clickedCallback': lambda x: self.escena.camara.activeLigths(), 
#        'releaseCallback':self.releaseAction},   
        
        {'path': path+"plane_x_y.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Posicionar: plano x-y', 
        'clickedCallback': lambda x: self.escena.objects[1].setPlano_x_y(), 
        'releaseCallback':self.releaseAction},   
        
        {'path': path+"plane_z_x.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Posicionar: plano z-x', 
        'clickedCallback': lambda x: self.escena.objects[1].setPlano_x_z(), 
        'releaseCallback':self.releaseAction},   
        
        {'path': path+"plane_y_z.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Posicionar: plano y-z', 
        'clickedCallback': lambda x: self.escena.objects[1].setPlano_y_z(), 
        'releaseCallback':self.releaseAction}, 
        
        #--
        {'path': path+"nurbsClose.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Ocultar todas las NURBS.', 
        'clickedCallback': lambda x: self.escena.set_all_nurbs_visibility('curve', False), 
        'releaseCallback':self.releaseAction}, 
        
        {'path': path+"nurbsOpen.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Visualizar todas las NURBS.', 
        'clickedCallback': lambda x: self.escena.set_all_nurbs_visibility('curve', True), 
        'releaseCallback':self.releaseAction}, 
        
        {'path': path+"poligonClose.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Ocultar todos los poligonos.', 
        'clickedCallback': lambda x: self.escena.set_all_nurbs_visibility('poligon', False), 
        'releaseCallback':self.releaseAction}, 
        
        {'path': path+"poligonOpen.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Visualizar todos los poligonos.', 
        'clickedCallback': lambda x: self.escena.set_all_nurbs_visibility('poligon', True), 
        'releaseCallback':self.releaseAction}, 
        
        {'path': path+"pointsClose.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Ocultar todos los puntos.', 
        'clickedCallback': lambda x: self.escena.set_all_nurbs_visibility('points', False), 
        'releaseCallback':self.releaseAction}, 
        
        {'path': path+"pointsOpen.png", 
        'widget':self.vent.get_widget('tableCamaraButtons'), 
        'toolTip':'Visualizar todos los puntos.', 
        'clickedCallback': lambda x: self.escena.set_all_nurbs_visibility('points', True), 
        'releaseCallback':self.releaseAction}, 
        ]
        
        cont = 1
        for button in buttons:
            path = button['path']
            tableWidget = button['widget']
            clickedCallback = button['clickedCallback']
            releaseCallback = button['releaseCallback']
            toolTip = button['toolTip']
            self.addButtonToTable(tableWidget, path, clickedCallback, releaseCallback, cont, 0, toolTip)
            cont += 1 # gtk.EXPAND, gtk.EXPAND

    def addButtonToTable(self, tableWidget, pathImage, clickedCallback, releaseCallback, contX, contY, toolTip='', xoptions=gtk.SHRINK, yoptions=gtk.SHRINK):
        ''' Agrega los botones a un tablewidget dado'''
        image = gtk.Image()
        image.set_from_file(pathImage)
        image.show()
        button = gtk.Button()
        button.connect("clicked", clickedCallback)
        button.connect("released", releaseCallback)
        button.add(image)
        button.set_tooltip_text(toolTip)
        button.show()
        tableWidget.attach(button, contX, contX+1, contY, contY + 1, xoptions, yoptions)

    def initializeTree(self):
        ''' Inicializa el arbol de elementos'''
        self.main_window = self.vent.get_widget('main_window')
        
        #iniciamos el treeview
        self.tree = self.vent.get_widget('treeview')

        self.model = gtk.TreeStore(  gobject.TYPE_INT,  #id 1
                                                    gobject.TYPE_INT, #id 2
                                                    gobject.TYPE_INT, #id 2
                                                    gobject.TYPE_STRING, #tipo del objeto
                                                    gobject.TYPE_STRING, #nombre del objeto
                                                    )
      
        #creamos las columnas
        cell = gtk.CellRendererText()
        spin = gtk.CellRendererSpin()
        columns = [gtk.TreeViewColumn('Id1',cell, text = 0), 
                          gtk.TreeViewColumn('Id2',cell, text = 1), 
                          gtk.TreeViewColumn('Id3',cell, text = 2), 
                          gtk.TreeViewColumn('TipoObjeto',cell, text = 3), 
                          gtk.TreeViewColumn('NombreObjeto',cell, text = 4)
                          ]
        
        #agregamos las columnas al treeview 
        for c in columns:
            self.tree.append_column(c)
        
        self.tree.set_model(self.model)
        
        #visibilidad nula para los ids
        for c in range(3):
            self.tree.get_column(c).set_property("visible", False)
        
        #se agregan los eventos de seleccion
        self.tree.connect('row-activated', self.selectRow)

    def saveProject(self, param1, param2=None):
        ''' Guarda los elementos en un archivo xml, esto esta implementado solo para guardar elementos NURBS'''
        #remuevo el glarea del hbox y lo guardo en un temporal
        childrens = self.hbox.get_children()
        glarea_temp = childrens[0]
        for children in childrens:
            self.hbox.remove(children)
            
        #obtiene el path donde se guardara
        path = self.openDialog(open=False)
        if path != None:
            path = path + '.xml'
            objs = self.escena.objects
            nurbs = []
            for n in objs.values():
                if(isinstance(n, NurbSurface)):
                    t = (n.name, n.cantU, n.cantV, n.ordenU, n.ordenV, n.ctrlPoints)
                    nurbs.append(t)
            xmlDoc = xmlNurbParser()
            if(path!=None):
                xmlDoc.writeXml(path, nurbs)
            
        #retorna el glarea
        self.glarea = glarea_temp
        self.hbox.pack_start(self.glarea, expand=True, fill=True)
        self.glarea.show()
        return 
    
    def enableArbol(self, a, b):#TODO
        self.vent.get_widget('scrolledwindow1').set_property('visible')
    
    def openProject(self, param1, param2=None):
        ''' Abre los elementos de un archivo xml, esto esta implementado solo para abrir elementos NURBS'''
        #remuevo el glarea del hbox y lo guardo en un temporal
        childrens = self.hbox.get_children()
        glarea_temp = childrens[0]
        for children in childrens:
            self.hbox.remove(children)
        
        path = self.openDialog(open=True)
        if path!=None:
            #vacia la lista de elementos de escena
            pass
            #TODO
            self.escena.deleteAllObjects()
        xmlDoc = xmlNurbParser()
        if(path!=None):
            nurbs = xmlDoc.readXml(path)
            ptos = []
            for n in nurbs:
                nombre = n[0]
                cantU = n[1]
                cantV = n[2]
                ordenU = n[3]
                ordenV = n[4]
                for p in n[5]:
                    exec('pt = '+ p)
                    ptos.append(pt)
                #superficie
                indice = self.escena.getNextIdentifier()
                u = int(cantU)
                v = int(cantV)
                if '.0' in ordenU:
                    ordenU = ordenU[:ordenU.find('.0')]
                if '.0' in ordenV:
                    ordenV = ordenV[:ordenV.find('.0')]
                oU = int(ordenU)
                oV = int(ordenV)
                nurbSurf = NurbSurface(indice, self.escena, [u, v, oU, oV])
                nurbSurf.name = nombre
                nurbSurf.setCtrlPoints(ptos)
                ptos = []
                self.escena.addObject(nurbSurf)
                #hace al objeto seleccionado
                self.escena.objects[indice].bSelected = True
                self.escena.selectedObject = self.escena.objects[indice]
        #retorna el glarea
        self.glarea = glarea_temp
        self.hbox.pack_start(self.glarea, expand=True, fill=True)
        self.glarea.show()
        #carga todo acerca del objeto
        self.cargarLeftBar()
        return

    def openDialog(self, open=True):
        ''' Abre un cuadro de dialogo'''
        # Check for new pygtk: this is new class in PyGtk 2.4
        if gtk.pygtk_version < (2,3,90):
           print "PyGtk 2.3.90 or later required for this example"
           raise SystemExit
        
        if(open):
            dialog = gtk.FileChooserDialog("Abrir.."
                                                        )
            dialog = gtk.FileChooserDialog("Abrir..",
                                           None,
                                           gtk.FILE_CHOOSER_ACTION_SAVE,
                                           (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        else:
            dialog = gtk.FileChooserDialog("Guardar.."
                                                        )
            dialog = gtk.FileChooserDialog("Guardar..",
                                           None,
                                           gtk.FILE_CHOOSER_ACTION_SAVE,
                                           (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_SAVE, gtk.RESPONSE_OK))

        filter = gtk.FileFilter()
        filter.set_name("All files")
        filter.add_pattern("*.xml")
        dialog.add_filter(filter)

        response = dialog.run()
        if response == gtk.RESPONSE_OK:
            path = dialog.get_filename()
        elif response == gtk.RESPONSE_CANCEL:
            path =  None
        dialog.destroy()
        return path

    def newNurb(self, widget):
        ''' Crea un nuevo elemento NURBS'''
        self.createNewElement(None, None, 'NurbSurface')
#        id = self.escena.getNextIdentifier()
#        obj = Cono(id, self.escena, ['1,1,1', '2,2,2', 0.5, 1, 'Cono'])
#        self.escena.addObject(obj)
#        self.escena.objects[id].bSelected = True

    #Colocar al objeto como elemento seleccionado TODO
    def selectRow(self, a, b, c):
        ''' Evento de seleccion de una fila del tree '''
        seleccion,iterador = self.tree.get_selection().get_selected()
        indice = seleccion.get_value(iterador,0)
        self.escena.selectedObject = self.escena.objects[indice]
        self.escena.selectNone()
        self.escena.selectedObject.bSelected = True
        self.cargarBotones(self.escena.selectedObject)
        self.cargarAtributos(self.escena.selectedObject)

    def canvas_button_scroll(self, widget, event, reloadAtributes = False):
        ''' Evento scroll del glarea, traslada el evento al objeto seleccionado '''
        direction = (event.direction == gtk.gdk.SCROLL_UP)
        self.escena.callbackScroll(direction, event.x, event.y)
        if reloadAtributes: #TODO
            self.cargarAtributos(self.escena.selectedObject)
            self.cargarBotones(self.escena.selectedObject)
    
    def cargarTree(self, objetos):
        ''' Carga el tree con los objetos seleccionados '''
        indice = 1
        self.model.clear()
        for key, value in objetos.items():
            fila = self.model.append(None, [int(key), int(key), int(key), value.type, value.name])

    def cargarBotones(self, objeto):
        ''' Carga los botones del objeto seleccionado en el area de botones'''
        #tabla de los botones
        btns = self.vent.get_widget('tableObjectsButton3')
        
        if(objeto.type != 'Camara'):
            #limpia la lista de botones
            childrens = btns.get_children()
            for children in childrens:
                btns.remove(children)
            
            labels = objeto.actionsToDo()
            labels.sort()
            contX = 0
            contY = 0
            cantHButtons = 1
            if labels.__len__() > 25:
                cantHButtons = 2
            if labels.__len__() > 50:
                cantHButtons = 3
            btns = self.vent.get_widget('tableObjectsButton3')
            rootPathImage = os.path.join(os.getcwd(), 'icons/')
#            rootPathImage = "/home/gush/adevelop/tesis/pruebas/tesisgeb/icons/"
            for label in labels:
                clickedCallback = self.escena.selectedObject.actions[label][0]
                toolTip = self.escena.selectedObject.actions[label][1]
                releaseCallback = self.releaseAction
                pathImage = rootPathImage+label[3:]
                self.addButtonToTable(btns, pathImage, clickedCallback, releaseCallback, contX, contY,  toolTip)
                contX += 1
                if(contX==cantHButtons):
                    contY += 1
                    contX = 0
        return

    def cargarAtributos(self, objeto):  
        ''' Carga los atributos del objeto seleccionado'''
        #Tabla de los atributos
        btns = self.vent.get_widget('tableObjectsAtributes')
        
        #Limpia la lista de botones
        childrens_Label = btns.get_children()
        for children in childrens_Label:
            btns.remove(children)
        
        objeto = self.escena.selectedObject
        atributes = objeto.atributesToEdit()
        labels = atributes.keys()
        labels.sort() 
        
        cont = 0
        for label in labels:
            #GtkLabel
            lab = gtk.Label(label)
            lab.show()
            btns.attach(lab, 0, 1, cont, cont+1, gtk.EXPAND, gtk.EXPAND)
            
            #GtkSpinButton
            value = atributes[label][0]
            maxValue = 100
            if isinstance(value, Vector3):
                adj1 = gtk.Adjustment(0.0, -maxValue, maxValue, 0.01, 0.01, 0.0)
                adj2 = gtk.Adjustment(0.0, -maxValue, maxValue, 0.01, 0.01, 0.0)
                adj3 = gtk.Adjustment(0.0, -maxValue, maxValue, 0.01, 0.01, 0.0)
                spinner1 = gtk.SpinButton(adj1, 1.0, 2)
                spinner2 = gtk.SpinButton(adj2, 1.0, 2)
                spinner3 = gtk.SpinButton(adj3, 1.0, 2)
                spinner1.set_value(value[0])
                spinner2.set_value(value[1])
                spinner3.set_value(value[2])
               
                if len(self.escena.selectedObject.atributes[label])==2: 
                    spinner1.connect("value_changed", self.escena.selectedObject.atributes[label][1], spinner1, spinner2, spinner3)
                    spinner2.connect("value_changed", self.escena.selectedObject.atributes[label][1], spinner1, spinner2, spinner3)
                    spinner3.connect("value_changed", self.escena.selectedObject.atributes[label][1], spinner1, spinner2, spinner3)
                elif len(self.escena.selectedObject.atributes[label])==3:
                    contPto = self.escena.selectedObject.atributes[label][2]
                    spinner1.connect("value_changed", self.escena.selectedObject.atributes[label][1], spinner1, spinner2, spinner3,contPto)
                    spinner2.connect("value_changed", self.escena.selectedObject.atributes[label][1], spinner1, spinner2, spinner3,contPto)
                    spinner3.connect("value_changed", self.escena.selectedObject.atributes[label][1], spinner1, spinner2, spinner3,contPto)
            
                btns.attach(spinner1, 1, 2, cont, cont+1)
                btns.attach(spinner2, 2, 3, cont, cont+1)
                btns.attach(spinner3, 3, 4, cont, cont+1)
                spinner1.show()
                spinner2.show()
                spinner3.show()
            else:
                
                adj1 = gtk.Adjustment(0.0, -maxValue, maxValue, 0.01, 0.01, 0.0)
                spinner1 = gtk.SpinButton(adj1, 1.0, 2)
                spinner1.set_value(value)
                if len(self.escena.selectedObject.atributes[label])==3:
                    contKnotU = self.escena.selectedObject.atributes[label][2]
                    spinner1.connect("value_changed", self.escena.selectedObject.atributes[label][1], contKnotU)
                else:
                    spinner1.connect("value_changed", self.escena.selectedObject.atributes[label][1])
                btns.attach(spinner1, 1, 2, cont, cont+1, gtk.EXPAND, gtk.SHRINK)
                spinner1.show()
            
            cont = cont + 1
            
        return

    def releaseAction(self, widget=None):
        ''' Release del area de trabajo '''
        self.escena.checkRemoves()
        self.cargarBotones(self.escena.selectedObject)
        self.cargarAtributos(self.escena.selectedObject)
        objetos = self.escena.getObject()
        self.cargarTree(objetos)

    def createNewElement(self, widget, event, className):
        ''' Crea un elemento para ser renderizado en el area de trabajo '''
        try:
            #Se consulta cuales son los botones que este necesita para ser creado
            exec('parameters =' + className + '.getParametersForCreate()')
            cant = parameters.__len__()
            
            #Se crea una ventana con labels y campos correspondientes a esos parametros
            ventana = self.vent.get_widget('windowsNuevosElementos')
            titulo = self.vent.get_widget('tituloNuevoElemento')
            tabla = self.vent.get_widget('tableNuevosElementos')
            
            for children in tabla.get_children():#borra los elementos de la tabla
                tabla.remove(children)
            
            stringTitulo = parameters[0]
            if(isinstance(stringTitulo, str)): #si se dispone de titulo se lo coloca
                titulo.set_text(stringTitulo)
                parameters.pop(0) #se extrae el titulo de la lista
            
            cont = 1
            entry = [] #lista en donde se almacena los valores para crear el objeto
            entryTypes = []
            for param in parameters:
                #Types
                entryTypes.append(param[1])
                #Label
                label = gtk.Label()
                label.set_text(param[0])
                label.set_justify(gtk.JUSTIFY_LEFT)
                label.show()
                #Entry
                entry.append(gtk.Entry())
                entry[cont-1].show()
                tabla.attach(label, 0, 1, cont, cont+1)
                tabla.attach(entry[cont-1], 1, 2, cont, cont+1)
                cont += 1
            ventana.show()
            self.className = className
            self.entries = entry 
            self.entryTypes = entryTypes
        except:
            print 'No es posible crear el elemento'
            self.alert('No es posible crear el elemento, es posible que exista una falla en la estructura del modulo.')
        return

    def cancelCreateNewElement(self, widget):
        ''' Presiona el boton cancelar del dialogo de crear un elemento'''
        self.vent.get_widget('windowsNuevosElementos').hide()
    
    def createAndAddNewElement(self, widget):
        ''' Crea y agrega el elemento'''
        entries = self.entries
        entryTypes = self.entryTypes
        className = self.className
        #Se convierten de string hacia los respectivos tipos
        cont = 0
        cant = entries.__len__()
        newEntries = []
        errorText = ''
        for entry in entries:
            valor = entry.get_text()
            try:
                valor = entryTypes[cont](valor) #lo convierte al tipo que corresponda
            except:
                errorText += 'Error: La entrada '+str(cont)+' debe ser de tipo '+str(entryTypes[cont]) + '\n'
                print 'Error: La entrada '+str(cont)+' debe ser de tipo '+str(entryTypes[cont])
                self.vent.get_widget('windowsNuevosElementos').hide()
            cont += 1
            newEntries.append(valor)
        if(errorText!=''):
            self.alert(errorText)
            return 0
        
        #Se crea el objeto con los parametros y se lo agrega a la Escena
        id = self.escena.getNextIdentifier()
        try:
            exec('obj =' + className + '(id, self.escena, newEntries)') #crea el objeto
            if(self.verifyCreation(obj)): #sino retorna False => se creo correctamente
                self.escena.addObject(obj)
                #hace al objeto seleccionado
                self.escena.objects[id].bSelected = True
                self.escena.selectedObject = self.escena.objects[id]
                self.vent.get_widget('windowsNuevosElementos').hide()
                self.cargarLeftBar()
            else:
                self.vent.get_widget('windowsNuevosElementos').hide()
                self.alert('Error: El objeto no se creo correctamente')
        except ImportError:
            self.vent.get_widget('windowsNuevosElementos').hide()
            self.alert('Error: El objeto no se creo correctamente')
    
    def verifyCreation(self, object):
        return object.success == True

    def deleteElement(self, widget, event, nameType):
        ''' Borra todos los elementos o algun tipo de ellos'''
        if(nameType=='Todos'):
            self.escena.deleteAllObjects()
        else:
            self.escena.deleteObjectByType(nameType)
        self.releaseAction()
        return 

    def cargarLeftBar(self):
        #objetos que maneja la escena
        objetos = self.escena.getObject()
        #carga el arbol de objetos
        self.cargarTree(objetos)
        #redibuja la pantalla
        self.escena.queue_draw()
        #carga los atributos
        #print 'objeto creado', self.escena.selectedObject
        self.cargarAtributos(self.escena.selectedObject)
        #carga los botones
        self.cargarBotones(self.escena.selectedObject)

    def alert (self, texto):
        ''' Despliega un dialogo de texto '''
        dialog = gtk.MessageDialog(
            parent= None,
            flags= gtk.DIALOG_DESTROY_WITH_PARENT,
            type= gtk.MESSAGE_INFO,
            buttons=gtk.BUTTONS_OK,
            message_format = texto)
        dialog.set_title('Alerta')
        dialog.set_modal (True)
        dialog.connect('response', lambda dialog, response: dialog.destroy())
        dialog.show_all()

    def set_info(self, text = 'this is the text'):
        label = self.vent.get_widget('set_info')
        label.set_text(text)

    def quit(self, param1, param2):
        ''' Cierra el programa '''
        gtk.main_quit()
    
    def run(self):
        ''' Lanza el programa '''
        gtk.main()

if __name__ == '__main__':
	app = Interfaz()
	app.run()



